/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-12-13     xu       the first version
 */
#include <rtthread.h>
#include "driver_spi.h"
#include "bsp_spi.h"
#include "board.h"

#define SPI_CLOCK_SPEED (12000 * 1000)
#define SPI_PIN_MAPPING 4 // G4 SPI1CLK(PE6), SPI1DI(PE5), SPI1DO(PE7)

static rt_sem_t spi_sem = RT_NULL;

RT_SECTION(".irq.spi")
static void spi_signal_event(uint32_t event)
{
    switch (event) {
        case 0x1:
            rt_sem_release(spi_sem);
            break;
        case 0x2:
            break;
        case 0x4:
            break;
    }
}

void bsp_spi_init(void)
{
    blue_driver_version_t version = RT_NULL;
    version = blue_spi1.get_version();
    rt_kprintf("version api:%d drv:%d\n", version->api, version->drv);

    spi_sem = rt_sem_create("spi_test", 0, RT_IPC_FLAG_FIFO);
    if (spi_sem == RT_NULL) {
        rt_kprintf("create spi_sem failed!");
    }

    int32_t ret = 0;
    blue_spi1.init(spi_signal_event);
    ret |= blue_spi1.control(BLUE_SPI_MODE_MASTER, SPI_CLOCK_SPEED);
    ret |= blue_spi1.control(BLUE_SPI_SET_MAPPING, SPI_PIN_MAPPING);
    ret |= blue_spi1.control(BLUE_SPI_ENABLE, 0);

    if (ret != 0) {
        rt_kprintf("spi init failed!");
    }
}

static rt_base_t int_state = 0;

void bsp_spi_lock(void)
{
    int_state = rt_hw_interrupt_disable();
}

void bsp_spi_unlock(void)
{
    rt_hw_interrupt_enable(int_state);
}

void bsp_spi_send(uint8_t byte)
{
    SPI1CON &= ~BIT(4);                             //TX
    SPI1BUF = byte;
    while (!(SPI1CON & BIT(16)));                   //Wait pending
}

uint8_t bsp_spi_recv()
{
    uint8_t value = 0;

    SPI1CON |= BIT(4);                              //RX
    SPI1BUF = 0x00;
    while (!(SPI1CON & BIT(16)));                   //Wait pending
    value = SPI1BUF;
    return value;
}

void bsp_spi_send_bytes(uint8_t* buffer, uint32_t size)
{
    for (uint32_t i = 0; i < size; i++) {
        bsp_spi_send(buffer[i]);
    }
}

void bsp_spi_recv_bytes(uint8_t* buffer, uint32_t size)
{
    for (uint32_t i = 0; i < size; i++) {
        buffer[i] = bsp_spi_recv();
    }
}
